#ifndef HTTP_HTTPSERVER_H_
#define HTTP_HTTPSERVER_H_

#include <fermat/net/tcp_server.h>
#include <fermat/net/socket_address.h>
#include <fermat/common/timestamp.h>
#include <fermat/common/buffer_slice.h>
#include <fermat/common/noncopyable.h>
#include <functional>

using fermat::any;
using fermat::Timestamp;
using fermat::PageBufferSliceQueuePtr;
using fermat::net::TcpConnectionPtr;
using fermat::net::TcpServer;
using fermat::net::SocketAddress;
using fermat::event::EventLoop;
using fermat::event::EventLoopPtr;


namespace fermat {
namespace http {
	
class HttpServerSession;

typedef std::function<bool(HttpServerSession*)> HttpSessionHadnler;

class HttpServer {
 public:
  HttpServer(EventLoopPtr loop,
             const SocketAddress& listenAddr,
             const std::string& name,
             TcpServer::Option option = TcpServer::kNoReusePort);

  ~HttpServer();  // force out-line dtor, for scoped_ptr members.

  EventLoopPtr getLoop() const { return _server.getLoop(); }

  /// Not thread safe, callback be registered before calling start().
  void setSessionBuilder(const HttpSessionHadnler &b)
  {
	 _builder = b;
  }

  void setSessionClear(const HttpSessionHadnler &b)
  {
	 _clear = b;
  }

  void setThreadNum(int numThreads)
  {
    _server.setThreadNum(numThreads);
  }

  void start();

 private:
  void onConnection(const TcpConnectionPtr& conn);
  void onMessage(const TcpConnectionPtr& conn,
                 PageBufferSliceQueuePtr buf, Timestamp receiveTime);
  void onWriteComplete(const TcpConnectionPtr& conn);
  
 private:
  TcpServer          _server;
  HttpSessionHadnler _builder;
  HttpSessionHadnler _clear;
};

}
}


#endif
